#ifndef COMMON_TYPE
#define COMMON_TYPE

//depend header
#include "boost\any.hpp"
#include <d3dx9.h>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <sstream>
#include <iostream>
#include <list>
#include <algorithm>
#include <assert.h>


typedef unsigned int uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
typedef int int32;
typedef short int16;
typedef char int8;
typedef unsigned __int64 uint64;
typedef __int64 int64;

typedef float Real;

#ifdef UNICODE
	typedef std::wstring		String;
	typedef std::wstringstream	StringStream;
#else
	typedef std::string			String;
	typedef std::stringstream	StringStream;
#endif

typedef boost::any Any;

namespace Common
{
	template<typename SpecificType>
	const SpecificType* any_cast(const Any* pAnyData)
	{
		return boost::any_cast<SpecificType>(pAnyData);
	}

	template<typename SpecificType>
	const SpecificType* any_cast(Any* pAnyData)
	{
		if( pAnyData->type() != typeid(SpecificType) )
		{
			const type_info& rSrcTypeInfo = pAnyData->type();
			const type_info& rTargetTypeInfo = typeid(SpecificType*);
			const std::string strSrcTypeName = rSrcTypeInfo.name();
			const std::string strTargetTypeName = rTargetTypeInfo.name();
		}
		return boost::any_cast<SpecificType>(pAnyData);
	}
	//////////////////////////////////////////////////////////////////
	/**
	* 32 bit float components
	*/
	class Float32
	{
	public:
		union
		{
			struct
			{
		
#if __AMD_BYTE_ORDER__
				DWORD	Sign : 1;
				DWORD	Exponent : 8;
				DWORD	Mantissa : 23;
#else __INTEL_BYTE_ORDER__
				DWORD	Mantissa : 23;
				DWORD	Exponent : 8;
				DWORD	Sign : 1;	
#endif
			} Components;

			FLOAT	FloatValue;
		};

		Float32( FLOAT InValue=0.0f )
			:	FloatValue(InValue)
		{}
	};
	///////////////////////////////////////////////////////
	///
	///
	class Float16
	{
	public:
		union
		{
			struct
			{

#if __AMD_BYTE_ORDER__
				WORD	Sign : 1;
				WORD	Exponent : 5;
				WORD	Mantissa : 10;
#else __INTEL_BYTE_ORDER__
				WORD	Mantissa : 10;
				WORD	Exponent : 5;
				WORD	Sign : 1;
#endif
			} Components;

			WORD	Encoded;
		};

		/** Default constructor */
		Float16( )
			:	Encoded(0)
		{
		}

		/** Copy constructor. */
		Float16( const Float16& FP16Value )
		{
			Encoded = FP16Value.Encoded;
		}

		/** Conversion constructor. Convert from Fp32 to Fp16. */
		Float16( FLOAT FP32Value )
		{
			Set( FP32Value );
		}	

		/** Assignment operator. Convert from Fp32 to Fp16. */
		Float16& operator=( FLOAT FP32Value )
		{
			Set( FP32Value );
			return *this;
		}

		/** Assignment operator. Copy Fp16 value. */
		Float16& operator=( const Float16& FP16Value )
		{
			Encoded = FP16Value.Encoded;
			return *this;
		}

		/** Convert from Fp16 to Fp32. */
		operator FLOAT() const
		{
			return GetFloat();
		}

		/** Convert from Fp32 to Fp16. */
		void Set( FLOAT FP32Value )
		{
			Float16 FP32(FP32Value);

			// Copy sign-bit
			Components.Sign = FP32.Components.Sign;

			// Check for zero, denormal or too small value.
			if ( FP32.Components.Exponent <= 112 )			// Too small exponent? (0+127-15)
			{
				// Set to 0.
				Components.Exponent = 0;
				Components.Mantissa = 0;
			}
			// Check for INF or NaN, or too high value
			else if ( FP32.Components.Exponent >= 143 )		// Too large exponent? (31+127-15)
			{
				// Set to 65504.0 (max value)
				Components.Exponent = 30;
				Components.Mantissa = 1023;
			}
			// Handle normal number.
			else
			{
				Components.Exponent = INT(FP32.Components.Exponent) - 127 + 15;
				Components.Mantissa = WORD(FP32.Components.Mantissa >> 13);
			}
		}

		/** Convert from Fp16 to Fp32. */
		FLOAT GetFloat() const
		{
			Float32	Result;

			Result.Components.Sign = Components.Sign;
			if (Components.Exponent == 0)
			{
				// Zero or denormal. Just clamp to zero...
				Result.Components.Exponent = 0;
				Result.Components.Mantissa = 0;
			}
			else if (Components.Exponent == 31)		// 2^5 - 1
			{
				// Infinity or NaN. Set to 65504.0
				Result.Components.Exponent = 142;
				Result.Components.Mantissa = 8380416;
			}
			else
			{
				// Normal number.
				Result.Components.Exponent = INT(Components.Exponent) - 15 + 127; // Stored exponents are biased by half their range.
				Result.Components.Mantissa = DWORD(Components.Mantissa) << 13;
			}

			return Result.FloatValue;
		}
	};

	class Vector2;
	class Vector3;
	class Vector4;
	class Matrix3;
	class Matrix4;
	class Quaternion;
	class Ray;
	class Plane;
	class Math;
	class Sphere;
	class AxisAlignedBox;
	class PlaneBoundedVolume;
	class Radian;
	class Degree;
	class Line2D;
	class Line3D;
	class ColourValue;
}

#endif